/**
 * 
 */
package server.room;

import server.exception.ServerException;

/**
 * Class representing single room - chess game
 * 
 * @author Kamil Nowak
 *
 */
public class Room {

	private Long id;
	private String name;
	
	private Long firstPlayer;
	private Long secondPlayer;
	private RoomState state = RoomState.FREE; 
	private Long userTurn;
	
	Room() {
		
	}

	/**
	 * Creates new room
	 * 
	 * @param connectionId room's owner's connection id
	 * @param roomId unique roomId
	 * @param name name of the room
	 */
	public Room(Long connectionId, Long roomId, String name) {
		this.id = roomId;
		this.name = name;
		this.firstPlayer = connectionId;
		this.userTurn = connectionId;
	}

	/**
	 * Returns secondPlayer (not owner) id
	 * @return secondPlayer connection id
	 */
	public Long getSecondPlayer() {
		return secondPlayer;
	}

	/**
	 * Second player joins the table
	 * if secondPlayer is null room is moved to the FREE state
	 * otherwise it is moved to OCCUPIED
	 * 
	 * @param secondPlayer player connection id or null
	 * @throws ServerException if table is already occupied
	 */
	public void setSecondPlayer(Long secondPlayer) throws ServerException {
		this.secondPlayer = secondPlayer;
		if (secondPlayer == null) moveToState(RoomState.FREE);
		else moveToState(RoomState.OCCUPIED);
	}

	/**
	 * Returns owner id 
	 * @return first playser connection id
	 */
	public Long getFirstPlayer() {
		return firstPlayer;
	}

	/**
	 * @return room id
	 */
	public Long getId() {
		return id;
	}

	/**
	 * @return room name
	 */
	public String getName() {
		return name;
	}


	/**
	 * Returns current room state 
	 * 
	 * @return state that room is in
	 */
	public RoomState getState() {
		return state;
	}

	/**
	 * Moves room to different state
	 * 
	 * @param newState new state label
	 * @throws ServerException if transision is impossible
	 */
	public void moveToState(RoomState newState) throws ServerException {
		if (!canMoveToState(newState)) throw new ServerException("No such transision");
		state = newState;
	}
	
	/**
	 * Moves room to differnet state and sets proper user turn
	 * 
	 * @param newState new state label
	 * @param connectionId player's connection id
	 * @throws ServerException if transision is impossible or not player's turn
	 */
	public void moveToState(RoomState newState,Long connectionId) throws ServerException {
		if (!canMoveToState(newState)) throw new ServerException(16);
		if (connectionId != firstPlayer && connectionId != secondPlayer) throw new ServerException("Improper user");
		if (newState == RoomState.MOVE || newState == RoomState.PROMO) {
			if (userTurn != connectionId) throw new ServerException(18);
			userTurn = connectionId == firstPlayer ? secondPlayer : firstPlayer;
		}
		state = newState;
	}

	private boolean canMoveToState(RoomState newState) {
		return RoomState.existsTransision(state,newState);
	}

	
	/**
	 * Changes user turn
	 */
	public void changeUserTurn() {
		userTurn = userTurn == firstPlayer ? secondPlayer : firstPlayer;
	}
	
	public Long getUserTurn() {
		return userTurn;
	}

	/**
	 * Return table player's id other then specified 
	 * 
	 * @param connectionId player connection id
	 * @return other player connection id
	 */
	public Long getOtherPlayer(Long connectionId) {
		if (connectionId == firstPlayer)
			return secondPlayer;
		else if (connectionId == secondPlayer)
			return firstPlayer;
		return null;
	}
	
}
